﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Abp.Auditing;
using Abp.Rebus.Core;
using Abp.Rebus.Rabbit;
using Abp.Runtime.Session;
using Castle.Core.Logging;
using Newtonsoft.Json;
using RabbitMQ.Client.Framing.Impl;
using Rebus.Bus;

namespace Abp.Rebus.Auditing
{

    public class AuditingBusStore : IAuditingStore
    {
        private readonly IBus _bus;
        private readonly ILogger _logger;
        private readonly IRabbitMqConnetionManager _rabbitMqConnetionManager;
        private readonly IAbpSession _apbSession;



        public AuditingBusStore(IBus bus, 
            ILogger logger, 
            IRabbitMqConnetionManager rabbitMqConnetionManager,
            IAbpSession apbSession)
        {
            _bus = bus;
            _logger = logger;
            _rabbitMqConnetionManager = rabbitMqConnetionManager;
            _apbSession = apbSession;
        }

        public async Task SaveAsync(AuditInfo auditInfo)
        {
            AuditMessage message = new AuditMessage()
            {
                BrowserInfo =auditInfo.BrowserInfo,
                ClientIpAddress =auditInfo.ClientIpAddress,
                ClientName =auditInfo.ClientName,
                CustomData =auditInfo.CustomData,
                ExecutionDuration =  auditInfo.ExecutionDuration,
                ExecutionTime = auditInfo.ExecutionTime,
                ImpersonatorTenantId =auditInfo.ImpersonatorTenantId,
                ImpersonatorUserId =auditInfo.ImpersonatorUserId,
                MethodName = auditInfo.MethodName,
                ServiceName=auditInfo.ServiceName,
                Parameters = auditInfo.Parameters,
                TenantId = auditInfo.TenantId,
                UserId =auditInfo.UserId,
            };

            if (auditInfo.Exception != null)
            {
                var sb = new StringBuilder();
                sb.AppendLine(auditInfo.Exception.Message);
                sb.AppendLine(auditInfo.Exception.StackTrace);
                sb.AppendLine(auditInfo.Exception.Source);
                if (auditInfo.Exception.InnerException != null)
                {
                    sb.AppendLine(auditInfo.Exception.InnerException.ToString());
                }
                message.Exception = sb.ToString();
            }
            try
            {
                _rabbitMqConnetionManager.Publish(message);
            }
            catch (Exception e)
            {
                _logger.Error(e.Message);
            }
        }
    }
}
